package com.boot.crm.java.collection.map;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Created by ys on 2018/8/3 13:44
 * 非线程安全，存储无序，键值均可以为null
 * hashMap底层结构是数组和entry链表结构，创建hashMap时会创建长度为16的数组，负载因子为0.75
 * 如果长度大于12会进行扩容(两倍)，
 * 扩容会很影响性能：原数组中的数据必须重新计算其在新数组中的位置，并放进去
 *
 * put进去一个(key,value),先对key调用hash()方法(还是hashcode方法)取得哈希值
 * 根据哈希值获取数组的下标，根据下标查看对应下标下是否有数据
 * 如果没有数据，直接放进去；如果有数据就比较key的equals方法，
 * 如果返回true，则value进行覆盖，key不覆盖；     返回值为原key
 * 如果key不同，新Entry将会和原Entry形成链表，新添加的Entry位于Entry的头部;  返回值为null
 *
 * hashTable为线程安全，键不可以为null(如：StringBuffer-->StringBuilder)
 */
public class HashMapMy<K,V> {
    public static void main(String[] args) {
//        cycleMap3();
        getMap();
    }
    private static Map<String,Object> getMap(){
        Map<String,Object> map = new HashMap<>();
        long l = System.currentTimeMillis();
        map.put("key1","value1");
        map.put("key2","value2");
        map.put("key3","value3");
        map.put("key4","value4");
        map.put("key5","value5");
        map.put("key6","value6");
        map.put("key7","value7");
        map.put("key8","value8");
        map.put("key9","value9");
        map.put("key10","value10");
        map.put("key11","value11");
        long l1 = System.currentTimeMillis();
        System.out.println((l1-l));
        map.put("key12","value12");
        map.put("key13","value13");
        map.put("key14","value14");
        long l2 = System.currentTimeMillis();
        System.out.println((l2-l1));
        return map;
    }
    //hashMap的循环：entrySet
    private static void cycleMap1(){
        Map<String, Object> map = getMap();
        Set<Map.Entry<String, Object>> entries = map.entrySet();
        for (Map.Entry<String, Object> entry:entries){
            String key = entry.getKey();
            Object value = entry.getValue();
            System.out.println(key+":"+value);
        }
    }
    //hashMap的循环：iterator
    private static void cycleMap2(){
        Map<String, Object> map = getMap();
        Set<Map.Entry<String, Object>> entries = map.entrySet();
        Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
        while (iterator.hasNext()){
            Map.Entry<String, Object> next = iterator.next();
            String key = next.getKey();
            Object value = next.getValue();
            System.out.println(key+":"+value);
        }

    }
    //hashMap的循环：java8的forEach
    private static void cycleMap3(){
        Map<String, Object> map = getMap();
        map.forEach((k,v)->{
            System.out.println(k+":"+v);
        });
    }
    //hashMap为什么不是线程安全？  http://www.importnew.com/21396.html
    //使用hashMap如何保证线程安全,如下3种实现方式
    private static void makeSureHashMapThreadSafe(){
        Hashtable<Object, Object> hashtable = new Hashtable<>();    //1.
        Map<Object, Object> synchronizedMap = Collections.synchronizedMap(new HashMap<>()); //2.、
        ConcurrentHashMap<Object, Object> concurrentHashMap = new ConcurrentHashMap<>();    //3.
    }
}
